<template>
	<div>
		<el-form ref="form" label-width="80px" :model="spu">
			<el-form-item label="SPU名称">
				<el-input placeholder="SPU名称" v-model="spu.spuName"></el-input>
			</el-form-item>
			<el-form-item label="品牌">
				<el-select placeholder="请选择品牌" v-model="spu.tmId">
					<el-option :label="tm.tmName" :value="tm.id" v-for="(tm, index) in tradeMarkList" :key="tm.id">
					</el-option>
				</el-select>
			</el-form-item>
			<el-form-item label="SPU描述">
				<el-input type="textarea" rows="4" placeholder="SPU描述" v-model="spu.description"></el-input>
			</el-form-item>
			<el-form-item label="SPU图片">
				<!-- 上传图片：
          action图片上传的地址
          list-type: 文件列表的类型
          on-preview:图片预览的时候会出发
          on-remove:当删除图片的时候会出发
          file-list：照片墙需要展示的数据【数组：数组里面的元素务必要有name、url属性】
          on-preview：图片预览功能
          on-remove:删除图片的时候会触发
        -->
				<el-upload action="/dev-api/admin/product/fileUpload" list-type="picture-card"
					:on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handlerSuccess"
					:file-list="spuImageList">
					<i class="el-icon-plus"></i>
				</el-upload>
				<!-- 预览大图 -->
				<el-dialog :visible.sync="dialogVisible">
					<img width="100%" :src="dialogImageUrl" alt="" />
				</el-dialog>
			</el-form-item>
			<el-form-item label="销售属性">
				<!-- value 用作存储收集数据 -->
				<el-select :placeholder="`还有${unSelectSaleAttr.length}未选择`" v-model="attrIdAndAttrName">
					<el-option :label="unselect.name" :value="`${unselect.id}:${unselect.name}`"
						v-for="(unselect, index) in unSelectSaleAttr" :key="unselect.id"></el-option>
				</el-select>
				<!-- :diabled 动态绑定disabled 禁用与否 为真时禁用  -->
				<el-button type="primary" icon="el-icon-plus" :disabled="!attrIdAndAttrName" @click="addSaleAttr">添加销售属性
				</el-button>
				<!-- 当前SPU自己销售属性  label标题数据 prop 内容数据-->
				<el-table style="width: 100%" border :data="spu.spuSaleAttrList">
					<el-table-column prop="prop" label="序号" width="80" type="index" align="center">
					</el-table-column>
					<el-table-column prop="saleAttrName" label="属性名" width="width">
					</el-table-column>
					<el-table-column prop="prop" label="属性值名称列表" width="width">
						<template slot-scope="{ row, $index }">
							<!-- row销售属性 -->
							<!-- el-tag:用户展示已有属性值列表的数据的 -->
							<el-tag :key="tag.id" v-for="(tag, index) in row.spuSaleAttrValueList" closable
								:disable-transitions="false" @close="row.spuSaleAttrValueList.splice(index, 1)">
								{{ tag.saleAttrValueName }}
							</el-tag>
							<!-- 底下的解构可以当中咱们当年的span与input切换 -->
							<!--  @keyup.enter.native="handleInputConfirm"  -->
							<!-- 此处inputVisible不能写在data中 el-tag有多个 控制input和 button切换隐藏 -->
							<el-input class="input-new-tag" v-if="row.inputVisible" v-model="row.inputValue"
								ref="saveTagInput" size="small" @blur="handleInputConfirm(row)">
							</el-input>
							<!-- @click="showInput" -->
							<el-button v-else class="button-new-tag" size="small" @click="addSaleAttrValue(row)">
								添加
							</el-button>
						</template>
					</el-table-column>
					<el-table-column prop="prop" label="操作" width="width">
						<template slot-scope="{ row, $index }">
							<el-button type="danger" icon="el-icon-delete" size="mini"
								@click="spu.spuSaleAttrList.splice($index, 1)">
							</el-button>
						</template>
					</el-table-column>
				</el-table>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" @click="addOrUpdateSpu">保存</el-button>
				<el-button @click="cancel">取消</el-button>
			</el-form-item>
		</el-form>
	</div>
</template>
<script>
	export default {
		name: "SpuForm",
		data() {
			return {
				dialogImageUrl: "",
				dialogVisible: false,
				spu: {
					//三级分类的id
					category3Id: 0,
					//描述
					description: "",
					//spu名称
					spuName: "",
					//平台的id
					tmId: "",
					//收集SPU图片的信息
					spuImageList: [
						// {
						//   id: 0,
						//   imgName: "string",
						//   imgUrl: "string",
						//   spuId: 0,
						// },
					],
					//平台属性与属性值收集
					spuSaleAttrList: [
						// {
						//   baseSaleAttrId: 0,
						//   id: 0,
						//   saleAttrName: "string",
						//   spuId: 0,
						//   spuSaleAttrValueList: [
						//     {
						//       baseSaleAttrId: 0,
						//       id: 0,
						//       isChecked: "string",
						//       saleAttrName: "string",
						//       saleAttrValueName: "string",
						//       spuId: 0,
						//     },
						//   ],
						// },
					],
				}, //存储SPU值属性 初始值为空对象 后期可以作收集数据
				tradeMarkList: [], //存储品牌信息
				spuImageList: [], //存储SPU图片数据
				saleAttrList: [], //销售属性的数据（项目全部的销售属性）
				attrIdAndAttrName: "", //收集未选择的销售属性ID
			};
		},
		methods: {
			//照片墙删除某一个图片的时候会触发
			handleRemove(file, fileList) {
				//file参数:代表的是删除的那个张图片
				//fileList:照片墙删除某一张图片以后，剩余的其他的图片
				// console.log(file, fileList,22222);
				//收集照片墙图片的数据
				//对于已有的图片【照片钱中显示的图片：有name、url字段的】，因为照片墙显示数据务必要有这两个属性
				//对于服务器而言，不需要name、url字段，将来对于有的图片的数据在提交给服务器的时候，需要处理的
				// 更新spuImageList
				this.spuImageList = fileList;
			},
			//照片墙图片预览的回调
			handlePictureCardPreview(file) {
				//将图片地址赋值给这个属性
				// console.log(file.url)
				this.dialogImageUrl = file.url;
				//对话框显示
				this.dialogVisible = true;
			},
			// 初始化SPUform数据
			async initSpuData(spu) {
				// 修改SPU时 需要向服务器发送请求 将服务器返回数据对象 赋值给SPU对象
				// 添加SPU时 未向服务器发请求 数据收集到SPU 但此处SPU初始值为空对象并不方便收集 不符合需求 需要根据文档设置对象
				// console.log('发请求',spu)
				// 获取SPU信息数据
				let spuResult = await this.$API.spu.reqSpu(spu.id);
				// console.log(spuResult)
				if (spuResult.code == 200) {
					this.spu = spuResult.data;
				}
				// 获取品牌信息
				let tradeMarkResult = await this.$API.spu.reqTradeMarkList();
				// console.log(tradeMarkResult)
				if (tradeMarkResult.code == 200) {
					this.tradeMarkList = tradeMarkResult.data;
				}
				// 获取SPU图片数据
				let spuImageResult = await this.$API.spu.reqSpuImageList(spu.id);
				// console.log(spuImageResult)
				if (spuImageResult.code == 200) {
					let listArr = spuImageResult.data;
					// 照片墙显示图片数组需要有name和url属性才会显示 故此处需先处理返回数据
					listArr.forEach((item) => {
						item.name = item.imgName;
						item.url = item.imgUrl;
					});
					// 把整理好的数据赋值给spuImageList
					this.spuImageList = listArr;
				}
				// 获取平台销售属性
				let saleResult = await this.$API.spu.reqBaseSaleAttrList();
				// console.log(saleResult)
				if (saleResult.code == 200) {
					this.saleAttrList = saleResult.data;
				}
			},
			// 照片墙图片上传成功回调
			handlerSuccess(response, file, fileList) {
				// file 上传成功的图片 fileList上传成功后的所有图片信息
				// console.log(response)  respone服务器返回信息
				this.spuImageList = fileList;
			},
			// 添加新的销售属性
			addSaleAttr() {
				// 把收集到的销售属性数据进行分割
				const [baseSaleAttrId, saleAttrName] = this.attrIdAndAttrName.split(":");
				// 整理数据
				let newSaleAttr = {
					baseSaleAttrId,
					saleAttrName,
					spuSaleAttrValueList: [],
				};
				// 向SPU对象spuSaleAttrList添加新的属性
				this.spu.spuSaleAttrList.push(newSaleAttr);
				// 清空数据
				this.attrIdAndAttrName = "";
			},
			// 点击添加按钮回调
			addSaleAttrValue(row) {
				// 点击添加销售属性值按钮时 button展示为input
				// console.log(row)
				// row.inputVisible = true 此处添加不是响应式 Vue无法检测到新添加的属性值
				// $set添加的新属性 Vue能检测到
				// 挂载在销售属性身上的响应式数据 控制button与input切换
				this.$set(row, "inputVisible", true);
				// 通过响应式数据inputValue字段设置为空 挂载到row销售属性上 收集新增销售属性值
				this.$set(row, "inputValue", "");
			},
			// el-input失去焦点事件
			handleInputConfirm(row) {
				// 修改inputViible为return false;
				row.inputVisible = false;
				// 解构销售属性当中收集数据
				// console.log(row)
				const {
					baseSaleAttrId,
					inputValue
				} = row;
				// 1 新增销售属性值不能为空
				if (inputValue.trim() == "") {
					this.$message("属性值不能为空");
					return;
				}
				// 2 新增属性值不能重复
				let result = row.spuSaleAttrValueList.every(
					(item) => item.saleAttrValueName != inputValue
				);
				// console.log(result)
				if (!result) {
					this.$message("属性值不能重复");
					return;
				}
				// 整理数据
				let newSaleAttrValue = {
					baseSaleAttrId,
					saleAttrValueName: inputValue
				};
				// 新增属性值数据
				row.spuSaleAttrValueList.push(newSaleAttrValue);
			},
			//保存按钮回调
			async addOrUpdateSpu() {
				// 整理参数
				// 整理图片照片墙数据 服务器需要携带imgName和imgUrl map返回一个新数组
				this.spu.spuImageList = this.spuImageList.map((item) => {
					return {
						imageName: item.name,
						imageUrl: (item.response && item.response.data) || item.url,
					};
				});
				// 发请求
				let result = await this.$API.spu.reqAddOrUpdateSpu(this.spu);
				// console.log(result)
				if (result.code == 200) {
					this.$message({
						type: "success",
						message: "保存成功",
					});
					// 通知父组件回到场景 0
					this.$emit("changeScene", {
						scene: 0,
						flag: this.spu.id ? "修改" : "添加",
					});
				}
				Object.assign(this._data, this.$options.data());
			},
			// 点击添加SPU 子组件发请求 回调函数
			async addSpuData(category3Id) {
				// 添加ＳＰＵ时收集三级分类ID
				this.spu.category3Id = category3Id;
				// 获取品牌信息
				let tradeMarkResult = await this.$API.spu.reqTradeMarkList();
				// console.log(tradeMarkResult)
				if (tradeMarkResult.code == 200) {
					this.tradeMarkList = tradeMarkResult.data;
				}
				// 获取平台销售属性
				let saleResult = await this.$API.spu.reqBaseSaleAttrList();
				// console.log(saleResult)
				if (saleResult.code == 200) {
					this.saleAttrList = saleResult.data;
				}
			},
			// 取消按钮回调
			cancel() {
				this.$emit("changeScene", {
					scene: 0,
					flag: ""
				});
				// 清理数据
				// Object.assign合并对象
				// this._data 当前挂载的响应式数据
				// this.$options.data()最开始配置对象
				Object.assign(this._data, this.$options.data());
			},
		},
		computed: {
			// 筛选还未选择的销售属性
			unSelectSaleAttr() {
				// 整个平台属性 saleAttrList
				// 当前SPU属于自己的SPU属性SPU.spuSaleAttrList
				// filter 从已有数组当中筛选出符合条件的元素 并返回新的数组
				let result = this.saleAttrList.filter((item) => {
					// console.log(item)
					// every数组方法 返回布尔值真或假 此处类双重for循环
					return this.spu.spuSaleAttrList.every((item1) => {
						return item.name != item1.saleAttrName;
					});
				});
				// 计算属性需要有返回值
				return result;
			},
		},
	};
</script>

<style scoped>
	.el-tag+.el-tag {
		margin-left: 10px;
	}

	.button-new-tag {
		margin-left: 10px;
		margin-top: 8px;
		height: 32px;
		line-height: 30px;
		padding-top: 0;
		padding-bottom: 0;
	}

	.input-new-tag {
		width: 90px;
		margin-left: 10px;
		vertical-align: bottom;
	}
</style>
